#include <jni.h>
#include <string>
#include <errno.h>
#include <fcntl.h>
#include <android/log.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/watchdog.h>

#define WATCHDOG_DEVICE_PATH "/dev/watchdog"
 int fd = -1;

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_watchdog_MainActivity_startWatchdog(JNIEnv *env, jobject thiz) {

    if (fd == -1) {
        fd = open(WATCHDOG_DEVICE_PATH, O_RDWR);
    }

    if (fd == -1) {
        __android_log_print(ANDROID_LOG_ERROR, "log", "Failed to open watchdog device %d", errno);
        return 0;
    }

    return 0;
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_watchdog_MainActivity_stopWatchdog(JNIEnv *env, jobject thiz) {
    if (fd > 0) {
        unsigned int val = WDIOS_DISABLECARD;
        int ret = ioctl(fd, WDIOC_SETOPTIONS,&val);
        if (ret == -1) {
            __android_log_print(ANDROID_LOG_ERROR, "log", "Failed to stop watchdog %d", errno);
        }
    }
    close(fd);

    return 0;
}

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_watchdog_MainActivity_pingWatchdog(JNIEnv *env, jobject thiz) {
    if (fd > 0) {
        int ret = ioctl(fd, WDIOC_KEEPALIVE);

        if (ret == -1) {
            __android_log_print(ANDROID_LOG_ERROR, "log", "Failed to send keep-alive signal %d", errno);
            perror("Failed to send keep-alive signal");
        }

        int ret2 ;
        ioctl(fd,WDIOC_GETTIMEOUT,&ret2);
        __android_log_print(ANDROID_LOG_ERROR, "log", "Watchdog timeout %d", ret2);
    }

    return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_watchdog_MainActivity_setWatchDogTimeout(JNIEnv *env, jobject thiz,
                                                              jstring timeout) {
    // TODO: implement set_WatchDog_Timeout()
    const char* timeoutStr = env->GetStringUTFChars(timeout, NULL);
    int timeoutInt = atoi(timeoutStr);
    if (fd >0){
        int ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeoutInt);
        if (ret == -1){
            __android_log_print(ANDROID_LOG_ERROR, "log", "Failed to set watchdog timeout %d", errno);
        }
    }
    return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_watchdog_MainActivity_getWatchDogTimeOut(JNIEnv *env, jobject thiz) {
    // TODO: implement getWatchDogTimeOut()
    if (fd >0){
        long val;
        ioctl(fd,WDIOC_GETTIMEOUT,&val);
        return val;
    } else{
        return 0;
    }
}